package com.fare.taluo.application.impl.analyse;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.hbase.client.Result;
import org.foreveross.hbase.client.HBaseHelper;
import org.foreveross.hbase.client.HBasePlaneinfoHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fare.taluo.application.analyse.AheadBuyTicketApplication;
import com.fare.taluo.application.plane.income.OccupRateApplication;
import com.fare.taluo.core.domain.config.channel.SourceEntity;
import com.fare.taluo.core.domain.config.city.PortEntity;
import com.fare.taluo.core.domain.config.line.FlightInfoEntity;
import com.fare.taluo.fusionCharts.FusionChartsTemplateModel;
import com.fare.taluo.fusionCharts.SimpleFusionChartsBuilder;
import com.fare.taluo.util.FusionChartsUtil_2;
import com.fare.taluo.util.I18nUtil;
import com.fare.taluo.util.flightInfo.FlightInfoSortUtil;
import com.fare.taluo.vo.core.OccupRateEntityVO;
import com.fare.taluo.vo.core.PlaneInfo;
@Transactional

@Service("aheadBuyTicketApplicationImpl")
public class AheadBuyTicketApplicationImpl implements AheadBuyTicketApplication{

	 private static final  String TabelName="LP_FLIGHT_HISTORY";//针对某个业务所查询的表一般是不会变的，所以写在里面就可以了，没必要作为参数传进来
	//rowkey: 渠道_区域ID_起点(使用三字码)_终点(使用三字码)_抓取时间(年月日)_航班日期(年月日时)_航班号
	 private static final int nAfterDay=-30;//查询的间隔为倒推30天
	 @Resource(name="occupRateApplication")
	 private OccupRateApplication occupRateService;
	 /**
	  * 核心业务说明
	  * 取数说明：假设今天是2013-07-20，航班日期设为2013-07-25，
	  * 则横轴日期为2013-07-25及之前的30天（共31天），
	  * 那么2013-07-20及之前的日期有数据，2013-07-20之后的无数据。（横轴始终有31天）
	  * 
	  * 
	  * PS 20130812
	  * 有一种比较特殊的情况，比如今天早上抓到的某个航班是15：00起飞，但是下午抓到的缺失16：00起飞
	  * oracle数据库只会保存一条记录。所以更新了最新的16：00，导致之前的15：00抓到的数据从这个16：00起飞的记录查不出来！！！
	  * 所以现在的策略是，数据库会保存多条记录，每个都有不同的起飞时间，我们业务逻辑里全部取出来，进行筛选最低价的航班。
	  * 所以新方法里参数去掉航班时间，因为页面进行排重之后已经失去了意义了，航班时间我们自己再次查询一次
	  * 														----  guokenye
	 * @throws Exception 
	  * 
	  */
	 
	 
	 
	 
	 
	 @Override
	public String getFusionChartsXMLStr(String fromCityCode,String toCityCode,
			String flightNo, String flightDate, String[] compareSourceHbaseKeys,Locale locale) throws Exception {
		 List<String> crawlDates=FusionChartsUtil_2.getDatesStr(flightDate,nAfterDay);//从航班日期开始往后面推30天，共31天
		 List<String> crawlDatesFormatMMdd=FusionChartsUtil_2.getDatesStrFormatMMdd(crawlDates);//截取MMdd
		 List<String> crawlDatesFormat=FusionChartsUtil_2.getDatesStrFormat(crawlDates);//替换所有的“-”
		 PortEntity pe=new PortEntity();
		 PortEntity from=pe.findByPortCode(fromCityCode);//出发城市实体
		 //PortEntity to=pe.findPortEntityByCityName(arrCityName);//到达城市实体
		 FlightInfoEntity fe=new FlightInfoEntity();
		 List<FlightInfoEntity> flights=fe.findByFlightNo(flightNo);//找出不同起飞时段的同一个航班
		 
		 
		 FusionChartsTemplateModel model=FusionChartsTemplateModel.getNewDefaultInstance();//报表模型
		 model.addChartAttr(FusionChartsTemplateModel.AN_Caption, flightNo+(null==I18nUtil.getProperties(locale).get("xmlutil.faleAndPLF")? " 运价与客座率走势":I18nUtil.getProperties(locale).get("xmlutil.faleAndPLF")));
		 model.addCategroyLabels(crawlDatesFormatMMdd);
		 
		 SourceEntity se=new SourceEntity();
		 flightNo =StringUtils.leftPad(flightNo, 8, '0');//航班号左补零
		 
		 long dataSetId=1000L;
		 for(String hbaseKey:compareSourceHbaseKeys){//数据来源的hbaseKey,罗列每一个来源，每一个就是一条线
			 SourceEntity s=se.findByHbaseKey(hbaseKey);
			 List<String> rowKeys=new ArrayList<String>();
			 for(String crawlDate:crawlDatesFormat){//每天
				 for(FlightInfoEntity f:flights){//有可能出现不同起飞时间段的航班
					 String flightDT=flightDate.replaceAll("-", "")+f.getFlightStartTime().substring(0,2);//航班日期(年月日时)
					 rowKeys.add(hbaseKey+from.getCode()+toCityCode+crawlDate+flightDT+flightNo); 
				 }
			 }
			 Result[] rs=HBaseHelper.getRecords(TabelName, rowKeys);//即时某个rowKey木有数据也会返回一个rs
			 List<PlaneInfo> infos=HBasePlaneinfoHelper.transformHBaseResultToPlaneinfo(rs);
			 //这里对数据进行过滤，取出每天的最低价，如果当天存在多个航班，取出最低的那个
			// infos=generatePlaneInfosByCondtions(infos,crawlDates);//按顺序得到每天最低价
			 infos=FlightInfoSortUtil.generatePlaneInfosOrderByCrawlDate(infos, crawlDates);
			 //把数据放入模型
			 model.createDataSet(dataSetId);
			 model.addDataSetAttr(dataSetId,FusionChartsTemplateModel.AN_Seriesname,(null==I18nUtil.getProperties(locale).get(s.getShortName())? s.getShortName():I18nUtil.getProperties(locale).get(s.getShortName())) );
			 model.addSetFullStrIntoDataSet(dataSetId, 
					 FusionChartsUtil_2.generateDashedByFormat(FusionChartsUtil_2.getPriceValueByPlaneInfosAndFormat(infos,locale),locale));
			 model.addDataSetAttr(dataSetId, FusionChartsTemplateModel.AN_RenderAs, "Line");//以折现展示数据
			 dataSetId++;
		 }
		 StringBuffer sb=new StringBuffer();
		//客座率
		//客座率现在有一个问题，存在每天数据不唯一的情况，所以代码需要验证，取出最高百分比的一条数据,而且最后返回的list的size肯定是31
		//客座率是手工导入的，所以领导要求数据只到今天就可以了，不要出现后面的数据，我们数据库已经到了2014年了
		 List<OccupRateEntityVO> kezuolvs=
				occupRateService.findOccupRateEntityByCondition(
						flightNo.replaceAll("^0*", ""),FusionChartsUtil_2.getDateAfterN(flightDate,nAfterDay ),
						FusionChartsUtil_2.todayBeforeFlightDate(flightDate)?//航班日期是否在今天之后，是的话只查到今天的数据，不是就查到航班日期的数据
								new Date():FusionChartsUtil_2.getDateAfterN(flightDate,0));
		
		 //kezuolvs=filterKezuolv(kezuolvs,FusionChartsUtil_2.getDatesStr(flightDate, nAfterDay));
		//sb.append("<dataset seriesName='客座率' parentYAxis='S' renderAs='Colum' color='8DA71E'>");
		 for(OccupRateEntityVO k:kezuolvs){
			sb.append("<set value='"+(k==null?"":k.getOccupRate())+"' />");
		 }
		 dataSetId++;
		 model.createDataSet(dataSetId);
		 model.addDataSetAttr(dataSetId, FusionChartsTemplateModel.AN_Seriesname, (null==I18nUtil.getProperties(locale).get("xmlutil.passengerLoad")? "客座率":I18nUtil.getProperties(locale).get("xmlutil.passengerLoad")));
		 model.addDataSetAttr(dataSetId, FusionChartsTemplateModel.AN_RenderAs, "Colum");
		 model.addDataSetAttr(dataSetId, FusionChartsTemplateModel.AN_ParentYAxis, "S");
		 model.addDataSetAttr(dataSetId, FusionChartsTemplateModel.AN_Color, "8DA71E");
		 model.addSetFullStrIntoDataSet(dataSetId, sb.toString());
		 model.addChartAttr(FusionChartsTemplateModel.AN_SNumberSuffix, "%");//客座率价格%
		 
		 model.addStyleToObject("ToolTip", FusionChartsTemplateModel.STYLE_ToolTip_FontSize_15);//全局style
		 model.addStyleToObject("Caption", FusionChartsTemplateModel.STYLE_Caption_FontSize_15);//全局style,标题15
		 String xml=SimpleFusionChartsBuilder.getInstance().buildXMLStr(model);
		 return xml;
	}
	 
	
	
	
	/**
	 * 获取整个‘提前购票’的报表XML字符串
	 */
	public String getAheadBuyTicketXML	(String depCityName,String arrCityName,
			String flightNo,String flightDate,String flightTime,
			String[] compareSourceHbaseKeys) throws Exception{
		return null;
	}
	public OccupRateApplication getOccupRateService() {
		return occupRateService;
	}
	public void setOccupRateService(OccupRateApplication occupRateService) {
		this.occupRateService = occupRateService;
	}
	
	
	private List<OccupRateEntityVO> filterKezuolv(List<OccupRateEntityVO> kezuolvs,List<String> dates)throws Exception{
		List<OccupRateEntityVO> finalResult=new ArrayList<OccupRateEntityVO>();
		Map<String,OccupRateEntityVO> temp=new HashMap<String,OccupRateEntityVO>();
		for(OccupRateEntityVO o:kezuolvs){
			if(o==null){
				continue;
			}
			if(temp.get(o.getFlightDayS())==null || 
					 temp.get(o.getFlightDayS()).getOccupRate().compareTo(o.getOccupRate())==-1){
				temp.put(o.getFlightDayS(), o);
			}
		}
		for(String date:dates){
			finalResult.add(temp.containsKey(date)?temp.get(date):null);
		}
		return  finalResult;
	}






	
	
	
	
}
